package com.brzjomo.secretiveworld.tileentity;

import javax.annotation.Nonnull;

import com.brzjomo.secretiveworld.SecretiveWorld;
import com.brzjomo.secretiveworld.init.ModBlocks;
import com.brzjomo.secretiveworld.init.ModTileEntityTypes;
import com.brzjomo.secretiveworld.inventory.container.CorpseOfAnUnknownTravelerContainer;
import com.brzjomo.secretiveworld.object.block.CorpseOfAnUnknownTravelerBlock;

import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ChestTileEntity;
import net.minecraft.tileentity.LockableLootTileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.NonNullList;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;

public class CorpseOfAnUnknownTravelerTileEntity extends LockableLootTileEntity{
	
	private int chestSize = 1 * 3;
	private NonNullList<ItemStack> chestContents = NonNullList.withSize(chestSize, ItemStack.EMPTY);
	protected int numPlayersUsing;
	private IItemHandlerModifiable items = createHandler();
	private LazyOptional<IItemHandlerModifiable> itemHandler = LazyOptional.of(() -> items);

	public CorpseOfAnUnknownTravelerTileEntity(TileEntityType<?> typeIn) {
		super(typeIn);
	}
	
	public CorpseOfAnUnknownTravelerTileEntity() {
		this(ModTileEntityTypes.CORPSE_OF_AN_UNKNOWN_TRAVELER.get());
	}

	@Override
	public int getSizeInventory() {
		return chestSize;
	}

	@Override
	public NonNullList<ItemStack> getItems() {
		return this.chestContents;
	}

	@Override
	public void setItems(NonNullList<ItemStack> itemsIn) {
		this.chestContents = itemsIn;
	}

	@Override
	protected ITextComponent getDefaultName() {
		return new TranslationTextComponent("container." + SecretiveWorld.MODID + ".corpse_of_an_unknown_traveler");
	}

	@Override
	protected Container createMenu(int idIn, PlayerInventory playerIn) {
		return new CorpseOfAnUnknownTravelerContainer(idIn, playerIn, this);
	}
	
	public void read(CompoundNBT compound) {
		super.read(compound);
		this.loadFromNbt(compound);
	}

	public CompoundNBT write(CompoundNBT compound) {
		super.write(compound);
		return this.saveToNbt(compound);
	}

	public void loadFromNbt(CompoundNBT compound) {
		this.chestContents = NonNullList.withSize(this.getSizeInventory(), ItemStack.EMPTY);
		if (!this.checkLootAndRead(compound) && compound.contains("Items", 9)) {
			ItemStackHelper.loadAllItems(compound, this.chestContents);
		}

	}

	public CompoundNBT saveToNbt(CompoundNBT compound) {
		if (!this.checkLootAndWrite(compound)) {
			ItemStackHelper.saveAllItems(compound, this.chestContents, false);
		}

		return compound;
	}
	
//	public boolean receiveClientEvent(int id, int type) {
//		if (id == 1) {
//			this.numPlayersUsing = type;
//			return true;
//		} else {
//			return super.receiveClientEvent(id, type);
//		}
//	}
	
	public void playSound(SoundEvent soundIn) {
		double d0 = (double) this.pos.getX() + 0.5D;
		double d1 = (double) this.pos.getY() + 0.5D;
		double d2 = (double) this.pos.getZ() + 0.5D;
		this.world.playSound((PlayerEntity)null, d0, d1, d2, soundIn, SoundCategory.BLOCKS, 0.5F,
				this.world.rand.nextFloat() * 0.1F + 0.9F);

	}
	
	private void scheduleTick() {
	      this.world.getPendingBlockTicks().scheduleTick(this.getPos(), this.getBlockState().getBlock(), 5);
	   }
	
	private void setOpenProperty(BlockState blockstate, boolean flag) {
	      this.world.setBlockState(this.getPos(), blockstate.with(CorpseOfAnUnknownTravelerBlock.PROPERTY_OPEN, Boolean.valueOf(flag)), 3);
	   }
	
	public void CorpsetTick() {
		int i = this.pos.getX();
	      int j = this.pos.getY();
	      int k = this.pos.getZ();
	      this.numPlayersUsing = ChestTileEntity.calculatePlayersUsing(this.world, this, i, j, k);
	      if (this.numPlayersUsing > 0) {
	         this.scheduleTick();
	      } else {
	         BlockState blockstate = this.getBlockState();
	         if (blockstate.getBlock() != ModBlocks.CORPSE_OF_AN_UNKNOWN_TRAVELER.get()) {
	        	 this.remove();
	             return;
	         }
	         
	         boolean flag = blockstate.get(CorpseOfAnUnknownTravelerBlock.PROPERTY_OPEN);
	         if (flag) {
	             this.playSound(SoundEvents.BLOCK_BARREL_CLOSE);
	             this.setOpenProperty(blockstate, false);
	          }
	       }
//		if (this.numPlayersUsing == 1) {
//			this.playSound(SoundEvents.ENTITY_SKELETON_STEP);
//		}
	}
	
	@Override
	public void openInventory(PlayerEntity player) {
		if (!player.isSpectator()) {
	         if (this.numPlayersUsing < 0) {
	            this.numPlayersUsing = 0;
	         }

	         ++this.numPlayersUsing;
	         BlockState blockstate = this.getBlockState();
	         boolean flag = blockstate.get(CorpseOfAnUnknownTravelerBlock.PROPERTY_OPEN);
	         if (!flag) {
	            this.playSound(SoundEvents.BLOCK_BARREL_OPEN);
	            this.setOpenProperty(blockstate, true);
	         }

	         this.scheduleTick();
	      }
	}

	@Override
	public void closeInventory(PlayerEntity player) {
		if (!player.isSpectator()) {
			--this.numPlayersUsing;
		}
	}
	
//	public static int getPlayersUsing(IBlockReader reader, BlockPos posIn) {
//		BlockState blockstate = reader.getBlockState(posIn);
//		if (blockstate.hasTileEntity()) {
//			TileEntity tileentity = reader.getTileEntity(posIn);
//			if (tileentity instanceof CrateTileEntity) {
//				return ((CrateTileEntity) tileentity).numPlayersUsing;
//			} else {
//				return 0;
//			}
//		} else {
//			return 0;
//		}
//	}
	
	public static void swapContents(CrateTileEntity tile1, CrateTileEntity tile2) {
		NonNullList<ItemStack> list = tile1.getItems();
		tile1.setItems(tile2.getItems());
		tile2.setItems(list);
	}

	@Override
	public void updateContainingBlockInfo() {
		super.updateContainingBlockInfo();
		if (this.itemHandler != null) {
			this.itemHandler.invalidate();
			this.itemHandler = null;
		}
	}
	
	@Override
	public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nonnull Direction side) {
		if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
			return itemHandler.cast();
		}
		return super.getCapability(cap, side);
	}

	private IItemHandlerModifiable createHandler() {
		return new InvWrapper(this);
	}

	@Override
	public void remove() {
		super.remove();
		if (itemHandler != null) {
			itemHandler.invalidate();
		}
	}
}
